package net.cyndeline.itemEventFactory.conditions

import net.cyndeline.stateEvaluation.Evaluator
import net.cyndeline.itemEventFactory.Action
import com.escalatesoft.subcut.inject.BindingModule
import net.cyndeline.itemEventFactory.ActionInput
import com.escalatesoft.subcut.inject.Injectable
import net.cyndeline.itemEventFactory.ActionInputStorage
import net.cyndeline.itemEventFactory.ActionInputConfig
import net.cyndeline.itemEventFactory.ActionResultConfig
import net.cyndeline.itemEventFactory.ActionResultStorage

class ConditionImpl(implicit val bindingModule: BindingModule) extends Condition with Injectable {
  private var evaluators = List[Evaluator]()
  private var actions = List[Action]()
  
  override var amount = 0
  
  override def addEvaluator(evaluatorList: Evaluator*) {
    for (evaluator <- evaluatorList) {
      evaluators = evaluators :+ evaluator
    }
  }
  
  override def addAction(actionList: Action*) {
    for (action <- actionList) {
      actions = actions :+ action
    }
  }
  
  override def events(indata: ActionInput) = {
    val newInput = injectOptional[ActionInputConfig] getOrElse { new ActionInputStorage() }
    val result = injectOptional[ActionResultConfig] getOrElse new ActionResultStorage()
    var filteredTargets = indata.allInput
    
    for (eval <- evaluators) {
      
      /* Take the intersection between the filter and the targets so far. */
      filteredTargets = filteredTargets & eval.evaluate(indata)
    }
    
    newInput.user = indata.user
    newInput.targets = filteredTargets.toList
    
    for (action <- actions) {
      val actionSet = action.events(newInput)
      for (targetActionPair <- actionSet.events) {
        result.addEvent(targetActionPair._1, targetActionPair._2)
      }
    }
    
    result
  }
}